package me.hgj.jetpackmvvm.base.viewmodel

import androidx.lifecycle.ViewModel
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.cancelChildren
import me.hgj.jetpackmvvm.base.viewmodel.BaseViewModel.Companion.LOADING_HIDE
import me.hgj.jetpackmvvm.base.viewmodel.BaseViewModel.Companion.LOADING_HIDE_SMART
import me.hgj.jetpackmvvm.base.viewmodel.BaseViewModel.Companion.LOADING_SHOW
import me.hgj.jetpackmvvm.util.livedata.unpeeklivedata_7.UnPeekLiveData

/**
 * 作者　: yuan_xh
 * 时间　: 2022/5/14
 * 描述　: ViewModel的基类 使用ViewModel类，放弃AndroidViewModel，原因：用处不大 完全有其他方式获取Application上下文
 */
open class BaseViewModel : ViewModel() {
    /**
     * viewModel内协程封装
     * */
    private val job = SupervisorJob()
    protected val uiScope = CoroutineScope(Dispatchers.Main + job)
    override fun onCleared() {
        super.onCleared()
        uiScope.coroutineContext.cancelChildren()
    }

    /**
     * 内置封装好的可通知Activity/fragment 显示隐藏加载框 因为需要跟网络请求显示隐藏loading配套才加的，不然我加他个鸡儿加
     */
    val stateLoading: LoadingStateLiveData by lazy { LoadingStateLiveData() }

    inner class StateLoadingInfo(var state: Int, var msg: String? = null) {
        fun call(
            dismissDialog: (() -> Unit)? = null,
            showDialog: ((String?) -> Unit)? = null,
            smartDismissDialog: (() -> Unit)? = null
        ) {
            when (state) {
                LOADING_HIDE -> dismissDialog?.invoke()
                LOADING_SHOW -> showDialog?.invoke(msg)
                LOADING_HIDE_SMART -> if (null == smartDismissDialog) dismissDialog?.invoke() else smartDismissDialog?.invoke()
            }
        }
    }

    inner class LoadingStateLiveData : UnPeekLiveData<StateLoadingInfo>() {
        override fun getValue(): StateLoadingInfo {
            return StateLoadingInfo(LOADING_HIDE)
        }

        fun showLoading(msg: String? = null) {
            postValue(StateLoadingInfo(LOADING_SHOW, msg))
        }

        fun dismissLoading() {
            postValue(StateLoadingInfo(LOADING_HIDE))
        }

        fun smartDismissLoading() {
            postValue(StateLoadingInfo(LOADING_HIDE_SMART))
        }

    }

    companion object {
        const val LOADING_SHOW = 2
        const val LOADING_HIDE_SMART = 1
        const val LOADING_HIDE = 0
    }
}

